# -*- coding:utf-8 -*-
# title           :
# description     :
# author          :Python超人/三月三提供
# date            :2024-08-17
# link            :https://gitcode.net/pythoncr/
# python_version  :3.9
# ==============================================================================
import math
import re

from 神笔码靓.神笔库.元素库.可操作元素集合 import 可操作元素集合
from 神笔码靓.神笔库.定义集 import *
from 神笔码靓.神笔库.配置 import *
from 神笔码靓.神笔库.通用工具集 import *
from 神笔码靓.神笔库 import 类型转换工具集
from dataclasses import dataclass


class 元素重复工具集:
    def __init__(self, 绘图板):
        from 神笔码靓.神笔库.神笔绘图板 import 神笔绘图板
        self.绘图板: 神笔绘图板 = 绘图板

    def 环绕重复(self, 重复元素, 重复数量: int, 环绕中心点: tuple[float, float] = None, 间距角: float = None,
             顺时针: bool = 是, 元素跟随旋转: bool = 是, 元素创造前回调=None, 元素创造后回调=None)-> 可操作元素集合:
        if 环绕中心点 is None:
            环绕中心点 = self.绘图板.宽 / 2, self.绘图板.高 / 2
        if 间距角 is None:
            间距角 = 360 / 重复数量

        if callable(重复元素):
            创造元素 = 重复元素
        else:
            if not isinstance(重复元素, list):
                重复元素 = [重复元素]
            重复模板 = self.绘图板.创建模板(元素列表=重复元素)
            创造元素 = lambda 参数: 重复模板.创造元素()

        元素列表 = 可操作元素集合(self.绘图板)

        if 元素跟随旋转:
            for i in 范围(重复数量):
                旋转角 = i * 间距角
                if not 顺时针:
                    旋转角 = -旋转角
                参数 = {"索引": i, "间距角": 间距角, "旋转角": 旋转角, "环绕中心点": 环绕中心点}
                if callable(元素创造前回调):
                    参数_ = 元素创造前回调(参数)
                    if 参数_ is not None:
                        参数 = 参数_
                元素 = 创造元素(参数).旋转(参数["旋转角"], 环绕中心点)
                if callable(元素创造后回调):
                    元素创造后回调(元素, 参数)
                元素列表.添加元素(元素)
        else:
            for i in 范围(重复数量):
                旋转角 = i * 间距角
                if not 顺时针:
                    旋转角 = -旋转角
                参数 = {"索引": i, "间距角": 间距角, "旋转角": 旋转角, "环绕中心点": 环绕中心点}
                if callable(元素创造前回调):
                    参数_ = 元素创造前回调(参数)
                    if 参数_ is not None:
                        参数 = 参数_
                元素 = 创造元素(参数)
                if callable(元素创造后回调):
                    元素创造后回调(元素, 参数)
                元素列表.添加元素(元素)
                if 旋转角 == 0:
                    continue
                位置信息 = 元素.获取位置信息()
                元素中心 = 位置信息.中心x, 位置信息.中心y
                元素新x, 元素新y = 计算旋转后的坐标(元素中心, 环绕中心点, 旋转角)
                元素.平移(元素新x - 位置信息.中心x, 元素新y - 位置信息.中心y)

        return 元素列表

    def 网格重复(self, 重复元素, 重复列数, 列间距: float, 重复行数, 行间距: float, 网格类型: 网格重复类型 = None)-> 可操作元素集合:
        # 普通网格、按列排砖型、按行排砖型（错开）
        if 网格类型 is None:
            网格类型 = 网格重复类型.普通网格

        if callable(重复元素):
            创造元素 = 重复元素
        else:
            if not isinstance(重复元素, list):
                重复元素 = [重复元素]
            重复模板 = self.绘图板.创建模板(元素列表=重复元素)
            创造元素 = lambda 参数: 重复模板.创造元素()

        元素列表 = 可操作元素集合(self.绘图板)

        for 行 in 范围(重复行数):
            for 列 in 范围(重复列数):
                参数 = {"行": 行, "列": 列}
                元素 = 创造元素(参数)
                元素列表.添加元素(元素)
                y = 行 * 行间距
                x = 列 * 列间距
                if 网格类型 == 网格重复类型.普通网格:
                    元素.平移(x, y)
                elif 网格类型 == 网格重复类型.砖型交错:
                    if 行 % 2 == 0:
                        x = x + 列间距 / 2
                    元素.平移(x, y)
                elif 网格类型 == 网格重复类型.竖砖交错:
                    if 列 % 2 == 0:
                        y = y + 行间距 / 2
                    元素.平移(x, y)

        return 元素列表

    def 垂直方向重复(self, 重复元素, 重复数量: int, 元素间距: float, 上中下="中", 中间空着=否) -> 可操作元素集合:
        if 上中下 is None:
            上中下 = "中"

        if 上中下 == "中":
            上面数 = 重复数量 // 2
            下面数 = 重复数量 - 上面数 - 1
        elif 上中下 == "上":
            上面数 = 重复数量 - 1
            下面数 = 0
        else:
            上面数 = 0
            下面数 = 重复数量 - 1

        if callable(重复元素):
            创造元素 = 重复元素
        else:
            if not isinstance(重复元素, list):
                重复元素 = [重复元素]
            重复模板 = self.绘图板.创建模板(元素列表=重复元素)
            创造元素 = lambda 参数: 重复模板.创造元素()

        元素列表 = 可操作元素集合(self.绘图板)

        if 中间空着:
            下面数 += 1
        else:
            参数 = {"上索引": None, "下索引": None}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)

        for i in 范围(1, 上面数 + 1):
            参数 = {"上索引": i, "下索引": None}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)
            元素.平移(0, -i * 元素间距)

        for i in 范围(1, 下面数 + 1):
            参数 = {"上索引": None, "下索引": i}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)
            元素.平移(0, i * 元素间距)

        return 元素列表

    def 水平方向重复(self, 重复元素, 重复数量: int, 元素间距: float, 左中右="中", 中间空着=否)-> 可操作元素集合:
        if 左中右 is None:
            左中右 = "中"

        if 左中右 == "中":
            左边数 = 重复数量 // 2
            右边数 = 重复数量 - 左边数 - 1
        elif 左中右 == "左":
            左边数 = 重复数量 - 1
            右边数 = 0
        else:
            左边数 = 0
            右边数 = 重复数量 - 1

        if callable(重复元素):
            创造元素 = 重复元素
        else:
            if not isinstance(重复元素, list):
                重复元素 = [重复元素]
            重复模板 = self.绘图板.创建模板(元素列表=重复元素)
            创造元素 = lambda 参数: 重复模板.创造元素()

        元素列表 = 可操作元素集合(self.绘图板)

        if 中间空着:
            右边数 += 1
        else:
            参数 = {"左索引": None, "右索引": None}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)

        for i in 范围(1, 左边数 + 1):
            参数 = {"左索引": i, "右索引": None}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)
            元素.平移(-i * 元素间距, 0)

        for i in 范围(1, 右边数 + 1):
            参数 = {"左索引": None, "右索引": i}
            元素 = 创造元素(参数)
            元素列表.添加元素(元素)
            元素.平移(i * 元素间距, 0)

        return 元素列表

    # def 镜像重复(self, 重复元素, 镜像线开始点, 镜像线结束点, ):
    #     pass


def 测试():
    from 神笔码靓.神笔库.神笔绘图板 import 神笔绘图板

    神笔 = 神笔绘图板("元素重复工具.svg")
    神笔.显示图框()

    圆 = 神笔.画圆(x=200, y=200, 半径=50, 填充颜色=颜色.蓝色)

    方 = 神笔.画矩形(x=200, y=200, 宽=60, 高=40, 填充颜色=颜色.红色).平移(100, 100)
    参考方 = 神笔.画矩形(x=180, y=180, 宽=100, 高=80, 填充颜色=颜色.蓝色).平移(100, 100)

    def 重复元素(参数):
        print(参数)
        return 神笔.画爱心(x=200, y=200, 半径大小=20, 填充颜色=颜色.红色).平移(100, 100)

    神笔.环绕重复(重复元素=圆, 重复数量=5, 间距角=30, 环绕中心点=(500, 500), 顺时针=否, 元素跟随旋转=否)
    神笔.网格重复(重复元素=[方], 重复列数=18, 列间距=60, 重复行数=16, 行间距=40, 网格类型=网格重复类型.砖型交错)
    神笔.垂直方向重复(重复元素=重复元素, 重复数量=8, 元素间距=40, 上中下="上")
    神笔.水平方向重复(重复元素=重复元素, 重复数量=3, 元素间距=70, 左中右="中")

    神笔.完成()


def 坐标系():
    from 神笔码靓.神笔库.神笔绘图板 import 神笔绘图板
    神笔 = 神笔绘图板("坐标系.svg")
    神笔.显示图框()
    中心点X, 中心点Y = (神笔.宽 / 2, 神笔.高 / 2)
    X轴长 = 神笔.宽 / 1.5
    Y轴长 = 神笔.高 / 1.5
    X轴半长 = X轴长 / 2
    Y轴半长 = Y轴长 / 2
    坐标点线段长 = 10

    神笔.箭头线(开始点=(中心点X - X轴半长, 中心点Y), 结束点=(中心点X + X轴半长, 中心点Y), 开始箭头=否, 箭头长度=20, 样式=箭头样式.实心)
    神笔.箭头线(开始点=(中心点X, 中心点Y + Y轴半长), 结束点=(中心点X, 中心点Y - Y轴半长), 开始箭头=否, 箭头长度=20, 样式=箭头样式.实心)

    坐标点X = 神笔.连直线([(中心点X, 中心点Y - 坐标点线段长), (中心点X, 中心点Y)])
    神笔.水平方向重复(重复元素=坐标点X, 重复数量=8, 元素间距=70, 左中右="中", 中间空着=是)

    坐标点Y = 神笔.连直线([(中心点X, 中心点Y), (中心点X + 坐标点线段长, 中心点Y)])
    神笔.垂直方向重复(重复元素=坐标点Y, 重复数量=8, 元素间距=70, 上中下="中", 中间空着=是)

    正弦波路径列表 = 列表()
    X偏移 = -360
    Y偏移 = 0  # 100
    Y幅度倍数 = 250
    频率 = 1  # 2
    for 角度 in 范围(0, 91, 30):
        x = 角度
        y = math.sin(角度 * 频率 * math.pi / 180) * Y幅度倍数 + Y偏移
        正弦波路径列表.添加元素((中心点X + x + X偏移, 中心点Y + y))

    # 正弦波 = 神笔.连线(路径点列表=正弦波路径列表, 描边颜色=颜色.绿色)
    正弦波 = 神笔.连曲线(路径点列表=正弦波路径列表, 描边颜色=颜色.绿色)
    # 神笔.显示关键点(关键点列表=正弦波路径列表, 关键点颜色=颜色.红色)

    神笔.完成()


if __name__ == '__main__':
    测试()
    # 坐标系()
